using System;
namespace ComponentAce.Compression.Libs.zlib
{
	internal sealed class Inflate
	{
		private const int MAX_WBITS = 15;
		private const int PRESET_DICT = 32;
		internal const int Z_NO_FLUSH = 0;
		internal const int Z_PARTIAL_FLUSH = 1;
		internal const int Z_SYNC_FLUSH = 2;
		internal const int Z_FULL_FLUSH = 3;
		internal const int Z_FINISH = 4;
		private const int Z_DEFLATED = 8;
		private const int Z_OK = 0;
		private const int Z_STREAM_END = 1;
		private const int Z_NEED_DICT = 2;
		private const int Z_ERRNO = -1;
		private const int Z_STREAM_ERROR = -2;
		private const int Z_DATA_ERROR = -3;
		private const int Z_MEM_ERROR = -4;
		private const int Z_BUF_ERROR = -5;
		private const int Z_VERSION_ERROR = -6;
		private const int METHOD = 0;
		private const int FLAG = 1;
		private const int DICT4 = 2;
		private const int DICT3 = 3;
		private const int DICT2 = 4;
		private const int DICT1 = 5;
		private const int DICT0 = 6;
		private const int BLOCKS = 7;
		private const int CHECK4 = 8;
		private const int CHECK3 = 9;
		private const int CHECK2 = 10;
		private const int CHECK1 = 11;
		private const int DONE = 12;
		private const int BAD = 13;
		internal int mode;
		internal int method;
		internal long[] long_0 = new long[1];
		internal long need;
		internal int marker;
		internal int nowrap;
		internal int wbits;
		internal InfBlocks blocks;
		private static byte[] mark = new byte[]
		{
			default(byte),
			default(byte),
			(byte)SupportClass.Identity(255L),
			(byte)SupportClass.Identity(255L)
		};
		internal int inflateReset(ZStream zstream_0)
		{
			if (zstream_0 != null && zstream_0.istate != null)
			{
				zstream_0.total_out = 0L;
				zstream_0.total_in = 0L;
				zstream_0.string_0 = null;
				zstream_0.istate.mode = ((zstream_0.istate.nowrap != 0) ? 7 : 0);
				zstream_0.istate.blocks.reset(zstream_0, null);
				return 0;
			}
			return -2;
		}
		internal int inflateEnd(ZStream zstream_0)
		{
			if (this.blocks != null)
			{
				this.blocks.free(zstream_0);
			}
			this.blocks = null;
			return 0;
		}
		internal int inflateInit(ZStream zstream_0, int int_0)
		{
			zstream_0.string_0 = null;
			this.blocks = null;
			this.nowrap = 0;
			if (int_0 < 0)
			{
				int_0 = -int_0;
				this.nowrap = 1;
			}
			if (int_0 >= 8 && int_0 <= 15)
			{
				this.wbits = int_0;
				zstream_0.istate.blocks = new InfBlocks(zstream_0, (zstream_0.istate.nowrap != 0) ? null : this, 1 << int_0);
				this.inflateReset(zstream_0);
				return 0;
			}
			this.inflateEnd(zstream_0);
			return -2;
		}
		internal int inflate(ZStream zstream_0, int int_0)
		{
			if (zstream_0 != null && zstream_0.istate != null && zstream_0.next_in != null)
			{
				int_0 = ((int_0 == 4) ? -5 : 0);
				int num = -5;
				while (true)
				{
					switch (zstream_0.istate.mode)
					{
					case 0:
						if (zstream_0.avail_in == 0)
						{
							return num;
						}
						num = int_0;
						zstream_0.avail_in--;
						zstream_0.total_in += 1L;
						if (((zstream_0.istate.method = (int)zstream_0.next_in[zstream_0.next_in_index++]) & 15) != 8)
						{
							zstream_0.istate.mode = 13;
							zstream_0.string_0 = "unknown compression method";
							zstream_0.istate.marker = 5;
							continue;
						}
						if ((zstream_0.istate.method >> 4) + 8 > zstream_0.istate.wbits)
						{
							zstream_0.istate.mode = 13;
							zstream_0.string_0 = "invalid window size";
							zstream_0.istate.marker = 5;
							continue;
						}
						zstream_0.istate.mode = 1;
						goto IL_2C5;
					case 1:
						goto IL_2C5;
					case 2:
						goto IL_49C;
					case 3:
						goto IL_506;
					case 4:
						goto IL_576;
					case 5:
						goto IL_5E7;
					case 6:
						goto IL_663;
					case 7:
						num = zstream_0.istate.blocks.proc(zstream_0, num);
						if (num == -3)
						{
							zstream_0.istate.mode = 13;
							zstream_0.istate.marker = 0;
							continue;
						}
						if (num == 0)
						{
							num = int_0;
						}
						if (num != 1)
						{
							return num;
						}
						num = int_0;
						zstream_0.istate.blocks.reset(zstream_0, zstream_0.istate.long_0);
						if (zstream_0.istate.nowrap != 0)
						{
							zstream_0.istate.mode = 12;
							continue;
						}
						zstream_0.istate.mode = 8;
						goto IL_1C4;
					case 8:
						goto IL_1C4;
					case 9:
						goto IL_14B;
					case 10:
						goto IL_D3;
					case 11:
						goto IL_2F;
					case 12:
						return 1;
					case 13:
						return -3;
					}
					return -2;
					IL_2F:
					if (zstream_0.avail_in == 0)
					{
						return num;
					}
					num = int_0;
					zstream_0.avail_in--;
					zstream_0.total_in += 1L;
					zstream_0.istate.need += (long)((ulong)zstream_0.next_in[zstream_0.next_in_index++] & 255uL);
					if ((int)zstream_0.istate.long_0[0] != (int)zstream_0.istate.need)
					{
						zstream_0.istate.mode = 13;
						zstream_0.string_0 = "incorrect data check";
						zstream_0.istate.marker = 5;
						continue;
					}
					goto IL_694;
					IL_D3:
					if (zstream_0.avail_in != 0)
					{
						num = int_0;
						zstream_0.avail_in--;
						zstream_0.total_in += 1L;
						zstream_0.istate.need += ((long)((long)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 8) & 65280L);
						zstream_0.istate.mode = 11;
						goto IL_2F;
					}
					return num;
					IL_14B:
					if (zstream_0.avail_in != 0)
					{
						num = int_0;
						zstream_0.avail_in--;
						zstream_0.total_in += 1L;
						zstream_0.istate.need += ((long)((long)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 16) & 16711680L);
						zstream_0.istate.mode = 10;
						goto IL_D3;
					}
					return num;
					IL_1C4:
					if (zstream_0.avail_in != 0)
					{
						num = int_0;
						zstream_0.avail_in--;
						zstream_0.total_in += 1L;
						zstream_0.istate.need = (long)((int)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 24 & -16777216);
						zstream_0.istate.mode = 9;
						goto IL_14B;
					}
					return num;
					IL_2C5:
					if (zstream_0.avail_in == 0)
					{
						return num;
					}
					num = int_0;
					zstream_0.avail_in--;
					zstream_0.total_in += 1L;
					int num2 = (int)(zstream_0.next_in[zstream_0.next_in_index++] & 255);
					if (((zstream_0.istate.method << 8) + num2) % 31 != 0)
					{
						zstream_0.istate.mode = 13;
						zstream_0.string_0 = "incorrect header check";
						zstream_0.istate.marker = 5;
					}
					else
					{
						if ((num2 & 32) != 0)
						{
							goto IL_490;
						}
						zstream_0.istate.mode = 7;
					}
				}
				return num;
				IL_490:
				zstream_0.istate.mode = 2;
				IL_49C:
				if (zstream_0.avail_in == 0)
				{
					return num;
				}
				num = int_0;
				zstream_0.avail_in--;
				zstream_0.total_in += 1L;
				zstream_0.istate.need = (long)((int)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 24 & -16777216);
				zstream_0.istate.mode = 3;
				IL_506:
				if (zstream_0.avail_in == 0)
				{
					return num;
				}
				num = int_0;
				zstream_0.avail_in--;
				zstream_0.total_in += 1L;
				zstream_0.istate.need += ((long)((long)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 16) & 16711680L);
				zstream_0.istate.mode = 4;
				IL_576:
				if (zstream_0.avail_in == 0)
				{
					return num;
				}
				num = int_0;
				zstream_0.avail_in--;
				zstream_0.total_in += 1L;
				zstream_0.istate.need += ((long)((long)(zstream_0.next_in[zstream_0.next_in_index++] & 255) << 8) & 65280L);
				zstream_0.istate.mode = 5;
				IL_5E7:
				if (zstream_0.avail_in == 0)
				{
					return num;
				}
				zstream_0.avail_in--;
				zstream_0.total_in += 1L;
				zstream_0.istate.need += (long)((ulong)zstream_0.next_in[zstream_0.next_in_index++] & 255uL);
				zstream_0.adler = zstream_0.istate.need;
				zstream_0.istate.mode = 6;
				return 2;
				IL_663:
				zstream_0.istate.mode = 13;
				zstream_0.string_0 = "need dictionary";
				zstream_0.istate.marker = 0;
				return -2;
				IL_694:
				zstream_0.istate.mode = 12;
				return 1;
			}
			return -2;
		}
		internal int inflateSetDictionary(ZStream zstream_0, byte[] dictionary, int dictLength)
		{
			int start = 0;
			int num = dictLength;
			if (zstream_0 != null && zstream_0.istate != null)
			{
				if (zstream_0.istate.mode == 6)
				{
					if (zstream_0._adler.adler32(1L, dictionary, 0, dictLength) != zstream_0.adler)
					{
						return -3;
					}
					zstream_0.adler = zstream_0._adler.adler32(0L, null, 0, 0);
					if (num >= 1 << zstream_0.istate.wbits)
					{
						num = (1 << zstream_0.istate.wbits) - 1;
						start = dictLength - num;
					}
					zstream_0.istate.blocks.set_dictionary(dictionary, start, num);
					zstream_0.istate.mode = 7;
					return 0;
				}
			}
			return -2;
		}
		internal int inflateSync(ZStream zstream_0)
		{
			if (zstream_0 == null || zstream_0.istate == null)
			{
				return -2;
			}
			if (zstream_0.istate.mode != 13)
			{
				zstream_0.istate.mode = 13;
				zstream_0.istate.marker = 0;
			}
			int num;
			if ((num = zstream_0.avail_in) == 0)
			{
				return -5;
			}
			int num2 = zstream_0.next_in_index;
			int num3 = zstream_0.istate.marker;
			while (num != 0 && num3 < 4)
			{
				if (zstream_0.next_in[num2] == Inflate.mark[num3])
				{
					num3++;
				}
				else
				{
					if (zstream_0.next_in[num2] != 0)
					{
						num3 = 0;
					}
					else
					{
						num3 = 4 - num3;
					}
				}
				num2++;
				num--;
			}
			zstream_0.total_in += (long)(num2 - zstream_0.next_in_index);
			zstream_0.next_in_index = num2;
			zstream_0.avail_in = num;
			zstream_0.istate.marker = num3;
			if (num3 != 4)
			{
				return -3;
			}
			long total_in = zstream_0.total_in;
			long total_out = zstream_0.total_out;
			this.inflateReset(zstream_0);
			zstream_0.total_in = total_in;
			zstream_0.total_out = total_out;
			zstream_0.istate.mode = 7;
			return 0;
		}
		internal int inflateSyncPoint(ZStream zstream_0)
		{
			if (zstream_0 != null && zstream_0.istate != null && zstream_0.istate.blocks != null)
			{
				return zstream_0.istate.blocks.sync_point();
			}
			return -2;
		}
	}
}
